<!DOCTYPE HTML>
<html>
<head>
<title>_HasDropDown unit test</title>

<script type="text/javascript" src="boilerplate.js"></script>

<script type="text/javascript">
require([
	"doh/runner",
	"dojo/_base/declare", "dojo/dom-geometry", "dojo/has", "dojo/keys", "dojo/on", "dojo/_base/window",
	"dijit/_HasDropDown", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
	"dijit/tests/helpers", "dojo/domReady!"
], function(doh, declare, domGeom, has, keys, on, win,
			_HasDropDown, _WidgetBase, _TemplatedMixin, helpers){


	var SimplePopup = declare([_WidgetBase, _TemplatedMixin], {
		// summary:
		//		A trivial popup widget

		label: "i'm a popup",
		templateString: "<div>${label}</div>"
	});

	var SimpleDropDownButton = declare([_WidgetBase, _TemplatedMixin, _HasDropDown], {
		// summary:
		//		A button that shows a popup.

		label: "show dropdown",
		popupLabel: "i'm a popup",
		orient: ["below"],

		templateString: "<button>${label}</button>",

		postCreate: function(){
			this.inherited(arguments);
			this.dropDown = new SimplePopup({
				id: this.id + "_popup",
				label: this.popupLabel
			});
		}
	});

	var NonFocusableDropDownButton = declare([_WidgetBase, _TemplatedMixin, _HasDropDown], {
		// summary:
		//		A non-focusable "button" that shows a popup.   Should work for mouse, although not for keyboard.

		label: "show popup (non-focusable)",
		orient: ["below"],

		templateString: "<span>${label}</span>",

		postCreate: function(){
			this.inherited(arguments);
			this.dropDown = new SimplePopup({
				id: this.id + "_popup",
				label: "popup from non-focusable"
			});
		}
	});

	// Synthetic events.   Could alternately use robot.
	function key(node, key){
		on.emit(node, "keydown", {
			keyCode: key,
			bubbles: true
		});
		on.emit(node, "keyup", {
			keyCode: key,
			bubbles: true
		});
	}
	function click(node){
		on.emit(node, has("pointer-events") ? "pointerdown" : has("MSPointer") ? "MSPointerDown" : "mousedown", {
			button: 0,	// left button (except on IE quirks mode, when it's 1)
			bubbles: true
		});
		on.emit(node, has("pointer-events") ? "pointerup" : has("MSPointer") ? "MSPointerUp" : "mouseup", {
			button: 0,	// left button (except on IE quirks mode, when it's 1)
			bubbles: true
		});
		on.emit(node, "click", {
			bubbles: true
		});
	}

	doh.register("basic", [
		function setup(){
			dd = new SimpleDropDownButton({
				id: "dd",
				label: "show dropdown - ltr"
			}).placeAt(win.body());
			popup = dd.dropDown;
			doh.t(!!popup, "popup exists");
		},
		function open(){
			var d = new doh.Deferred();
			click(dd.domNode);
			setTimeout(d.getTestCallback(function(){
				doh.t(helpers.isVisible(popup), "popup visible");
				var anchorPos = domGeom.position(dd.domNode),
					dropDownPos = domGeom.position(popup.domNode);
				doh.t(Math.abs(anchorPos.x - dropDownPos.x) < 1, "drop down and anchor left aligned");
				doh.t(Math.abs(anchorPos.w - dropDownPos.w) < 1, "drop down same width as anchor");
			}), 10);
			return d;
		},
		function close(){
			dd.closeDropDown();
			doh.t(helpers.isHidden(popup), "popup hidden");
		},
		function openBySpace(){
			var d = new doh.Deferred();
			key(dd.domNode, keys.SPACE);
			setTimeout(d.getTestCallback(function(){
				doh.t(!!popup, "popup exists");
				doh.t(helpers.isVisible(popup), "popup visible again");
			}), 10);
			return d;
		},
		function close2(){
			dd.closeDropDown();
			doh.t(helpers.isHidden(popup), "popup hidden again");
		}
		// TODO: open by down arrow
	]);

	doh.register("rtl", [
		function setup(){
			dd = new SimpleDropDownButton({
				id: "rdd",
				dir: "rtl",
				label: "show dropdown - rtl"
			}).placeAt(win.body());
			popup = dd.dropDown;
			doh.t(!!popup, "popup exists");
		},
		function open(){
			var d = new doh.Deferred();
			click(dd.domNode);
			setTimeout(d.getTestCallback(function(){
				doh.t(helpers.isVisible(popup), "popup visible");
				var anchorPos = domGeom.position(dd.domNode),
					dropDownPos = domGeom.position(popup.domNode);
				doh.t(Math.abs(anchorPos.x - dropDownPos.x) < 1, "drop down and anchor left aligned");
				doh.t(Math.abs(anchorPos.w - dropDownPos.w) < 1, "drop down same width as anchor");
			}), 10);
			return d;
		}
	]);

	doh.register("non focusable", [
		function setup(){
			ndd = new NonFocusableDropDownButton({id: "ndd"}).placeAt(win.body());
			popup = ndd.dropDown;
			doh.t(!!popup, "popup exists");
		},
		function open(){
			var d = new doh.Deferred();
			click(ndd.domNode);
			setTimeout(d.getTestCallback(function(){
				doh.t(helpers.isVisible(popup), "popup visible");
			}), 10);
			return d;
		},
		function close(){
			ndd.closeDropDown();
		}
	]);

	doh.register("alignment", [
		function left(){
			var d = new doh.Deferred();
			var ltr = new SimpleDropDownButton({
				id: "ltr",
				label: "show non-auto-width dropdown - ltr",
				autoWidth: false
			}).placeAt(win.body());
			click(ltr.domNode);
			setTimeout(d.getTestCallback(function(){
				var anchorPos = domGeom.position(ltr.domNode),
					dropDownPos = domGeom.position(ltr.dropDown.domNode);
				doh.t(Math.abs(anchorPos.x - dropDownPos.x) < 1, "drop down and anchor left aligned");
				doh.t(anchorPos.w > dropDownPos.w, "anchor wider than drop down");
			}), 10);
			return d;
		},
		function right(){
			var d = new doh.Deferred();
			var rtl = new SimpleDropDownButton({
				id: "rtl",
				dir: "rtl",
				label: "show non-auto-width dropdown - rtl",
				autoWidth: false
			}).placeAt(win.body());
			click(rtl.domNode);
			setTimeout(d.getTestCallback(function(){
				var anchorPos = domGeom.position(rtl.domNode),
					dropDownPos = domGeom.position(rtl.dropDown.domNode);
				doh.t(Math.abs((anchorPos.x + anchorPos.w) - (dropDownPos.x + dropDownPos.w)) < 1,
						"drop down and anchor right aligned");
				doh.t(anchorPos.w > dropDownPos.w, "anchor wider than drop down");
			}), 10);
			return d;
		}
	]);

	doh.register("destroy", [
		function setup(){
			dd = new SimpleDropDownButton({id: "dd2"}).placeAt(win.body());
			popup = dd.dropDown;
			doh.t(!!popup, "popup exists");
		},
		function open(){
			var d = new doh.Deferred();
			click(dd.domNode);
			setTimeout(d.getTestCallback(function(){
				doh.t(helpers.isVisible(popup), "popup visible");
				doh.is(1, require("dijit/popup")._stack.length, "in popup manager stack");
			}), 10);
			return d;
		},
		function destroy(){
			dd.destroy();
			doh.is(0, require("dijit/popup")._stack.length, "popup was closed");
		}
	]);

	doh.run();
});
</script>
</head>
<body>
<h1>_HasDropDown Unit Test</h1>
</body>
</html>
